package rkw.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import rkw.communication.ClientChecker;
import rkw.communication.CommunicationService;
import rkw.communication.CommunicationServiceImpl;
import rkw.communication.InvocationHandler;
import rkw.communication.InvocationHandlerImpl;
import rkw.communication.MessageReceiver;
import rkw.communication.MessageSender;
import rkw.communication.Server;
import rkw.database.DatabaseService;
import rkw.database.DatabaseServiceImpl;
import rkw.election.ElectionService;
import rkw.election.ElectionServiceImpl;
import rkw.gui.MainWindow;
import rkw.manager.ManagerController;
import rkw.manager.ManagerControllerImpl;
import rkw.packager.PackagerService;
import rkw.packager.PackagerServiceImpl;
import rkw.utils.BeanProvider;
import core.smartCardReader.SmartCardReaderService;

@Configuration
public class ApplicationConfig {
	@Autowired
	private DatabaseService databaseService;

	@Autowired
	private Server server;

	@Autowired
	private MessageSender messageSender;

	@Autowired
	private MessageReceiver messageReceiver;

	@Autowired
	private ClientChecker clientChecker;

	@Autowired
	private CommunicationService communicationService;
	
	@Autowired
	private PackagerService packagerService;

	@Autowired
	private ElectionService electionService;

	@Autowired
	private InvocationHandler invocationHandler;

	@Autowired
	private SmartCardReaderService smartCardReaderService;

	@Autowired
	private BeanProvider beanProvider;

	@Autowired
	private MainWindow mainWindow;

	@Autowired
	private ManagerController managerController;

	@Bean
	public DatabaseService databaseService() {
		return new DatabaseServiceImpl();
	}

	@Bean
	public ManagerController managerController() {
		return new ManagerControllerImpl(mainWindow, databaseService, communicationService);
	}

	@Bean
	public CommunicationService communicationService() {
		return new CommunicationServiceImpl(databaseService, server, messageSender, messageReceiver, clientChecker, taskExecutor());
	}

	@Bean
	public InvocationHandler invocationHandler() {
		return new InvocationHandlerImpl(communicationService, databaseService);
	}

	@Bean
	public MainWindow mainWindow() {
		return new MainWindow();
	}

	@Bean
	public Server server() {
		return new Server();
	}

	@Bean
	public MessageSender messageSender() {
		return new MessageSender();
	}

	@Bean
	public MessageReceiver messageReceiver() {
		return new MessageReceiver();
	}

	@Bean
	public ClientChecker clientChecker() {
		return new ClientChecker();
	}

	@Bean
	public ThreadPoolTaskExecutor taskExecutor() {
		ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
		pool.setCorePoolSize(5);
		pool.setMaxPoolSize(10);
		pool.setWaitForTasksToCompleteOnShutdown(true);
		return pool;
	}

	@Bean
	public ElectionService electionService() {
		return new ElectionServiceImpl(databaseService, communicationService, packagerService);
	}

	@Bean
	public SmartCardReaderService smartCardReaderService() {
		return new SmartCardReaderService();
	}

	@Bean
	public BeanProvider beanProvider() {
		return new BeanProvider();
	}

	@Bean
	public PackagerService packagerService() {
		return new PackagerServiceImpl();
	}
}
